/**
 * jQuery EasyUI 1.4.3
 * 
 * Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
 *
 * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
 * To use it on other terms please contact us at info@jeasyui.com
 *
 */
/**
 * form - jQuery EasyUI
 * 
 */
(function($) {

 /**
  * 设置kendoWidget值.
  */
 function kendoWidgetSetValue(that, val) {
  var kendoWidgets = [ 'kendoDropDownList', 'kendoNumericTextBox', 'kendoKindEditor' ];
  for (var i = 0; i < kendoWidgets.length; i++) {
   var thatWidget = $(that).data(kendoWidgets[i]);
   if (thatWidget) {
    // console.log(kendoWidgets[i]+':kendoWidgetSetValue:'+val);
    thatWidget.value(val);
    return true;
   }
  }
  return false;
 }

 /**
  * 设置指定form,指定name的kendoWidget值.
  */
 function kendoFormFieldSetValue(target, name, val) {
  var form = $(target);
  // 支持kendoui widget {.
  form.find('input[name="' + name + '"]').each(function(i) {
   var result = kendoWidgetSetValue(this, val);
   if (result) {
    return true;
   }
  });
  form.find('textarea[name="' + name + '"]').each(function(i) {
   var result = kendoWidgetSetValue(this, val);
   if (result) {
    return true;
   }
  });
  // 支持kendoui widget }.
  return false;
 }

 /**
  * submit the form
  */
 function ajaxSubmit(target, options) {
  var opts = $.data(target, 'form').options;
  $.extend(opts, options || {});

  var param = $.extend({}, opts.queryParams);
  if (opts.onSubmit.call(target, param) == false) {
   return;
  }
  $(target).find('.textbox-text:focus').blur();

  var frameId = 'easyui_frame_' + (new Date().getTime());
  var frame = $('<iframe id=' + frameId + ' name=' + frameId + '></iframe>').appendTo('body')
  frame.attr('src', window.ActiveXObject ? 'javascript:false' : 'about:blank');
  frame.css({
   position : 'absolute',
   top : -1000,
   left : -1000
  });
  frame.bind('load', cb);

  submit(param);

  function submit(param) {
   var form = $(target);
   if (opts.url) {
    form.attr('action', opts.url);
   }
   var t = form.attr('target'), a = form.attr('action');
   form.attr('target', frameId);
   var paramFields = $();
   try {
    for ( var n in param) {
     var field = $('<input type="hidden" name="' + n + '">').val(param[n]).appendTo(form);
     paramFields = paramFields.add(field);
    }
    checkState();
    form[0].submit();
   } finally {
    form.attr('action', a);
    t ? form.attr('target', t) : form.removeAttr('target');
    paramFields.remove();
   }
  }

  function checkState() {
   var f = $('#' + frameId);
   if (!f.length) {
    return

    

        

    

   }
   try {
    var s = f.contents()[0].readyState;
    if (s && s.toLowerCase() == 'uninitialized') {
     setTimeout(checkState, 100);
    }
   } catch (e) {
    cb();
   }
  }

  var checkCount = 10;
  function cb() {
   var f = $('#' + frameId);
   if (!f.length) {
    return

    

        

    

   }
   f.unbind();
   var data = '';
   try {
    var body = f.contents().find('body');
    data = body.html();
    if (data == '') {
     if (--checkCount) {
      setTimeout(cb, 100);
      return;
     }
    }
    var ta = body.find('>textarea');
    if (ta.length) {
     data = ta.val();
    } else {
     var pre = body.find('>pre');
     if (pre.length) {
      data = pre.html();
     }
    }
   } catch (e) {
   }
   opts.success(data);
   setTimeout(function() {
    f.unbind();
    f.remove();
   }, 100);
  }
 }

 /**
  * load form data if data is a URL string type load from remote site, otherwise
  * load from local data object.
  */
 function load(target, data) {
  var opts = $.data(target, 'form').options;

  if (typeof data == 'string') {
   var param = {};
   if (opts.onBeforeLoad.call(target, param) == false)
    return;

   $.ajax({
    url : data,
    data : param,
    dataType : 'json',
    success : function(data) {
     _load(data);
    },
    error : function() {
     opts.onLoadError.apply(target, arguments);
    }
   });
  } else {
   _load(data);
  }

  function _load(data) {
   var form = $(target);
   for ( var name in data) {
    var val = data[name];
    // 支持kendoui widget
    if (kendoFormFieldSetValue(target, name, val)) {
     return;
    }
    if (!_checkField(name, val)) {
     if (!_loadBox(name, val)) {
      form.find('input[name="' + name + '"]').val(val);
      form.find('textarea[name="' + name + '"]').val(val);
      form.find('select[name="' + name + '"]').val(val);
      form.find('span[name="' + name + '"]').text(val);
      form.find('div[name="' + name + '"]').text(val);
      form.find('p[name="' + name + '"]').html(val);
      form.find('img[name="' + name + '"]').prop('src', val);
     }
    }
   }
   // 扩展
   _loadExtend(target, data);
   opts.onLoadSuccess.call(target, data);
   form.form('validate');
  }

  // 扩展
  function _loadExtend(target, data) {
   // kendoBootstrapFileInput
   $(target).find("[data-role='bootstrapfileinput']").each(function() {
    $(this).data('kendoBootstrapFileInput').sync();
   });
  }

  /**
   * check the checkbox and radio fields
   */
  function _checkField(name, val) {
   var cc = $(target).find('[switchbuttonName="' + name + '"]');
   if (cc.length) {
    cc.switchbutton('uncheck');
    cc.each(function() {
     if (_isChecked($(this).switchbutton('options').value, val)) {
      $(this).switchbutton('check');
     }
    });
    return true;
   }
   cc = $(target).find('input[name="' + name + '"][type=radio], input[name="' + name + '"][type=checkbox]');
   if (cc.length) {
    cc._propAttr('checked', false);
    cc.each(function() {
     if (_isChecked($(this).val(), val)) {
      $(this)._propAttr('checked', true);
     }
    });
    return true;
   }
   return false;
  }
  function _isChecked(v, val) {
   if (v == String(val) || $.inArray(v, $.isArray(val) ? val : [ val ]) >= 0) {
    return true;
   } else {
    return false;
   }
  }

  function _loadBox(name, val) {
   var field = $(target).find('[textboxName="' + name + '"],[sliderName="' + name + '"]');
   if (field.length) {
    for (var i = 0; i < opts.fieldTypes.length; i++) {
     var type = opts.fieldTypes[i];
     var state = field.data(type);
     if (state) {
      if (state.options.multiple || state.options.range) {
       field[type]('setValues', val);
      } else {
       field[type]('setValue', val);
      }
      return true;
     }
    }
   }
   return false;
  }
 }

 /**
  * clear the form fields
  */
 function clear(target) {
  $('input,select,textarea,span,img', target).each(function() {
   var t = this.type, tag = this.tagName.toLowerCase();
   var that = this;
   var name = $(that).attr('name');
   var hasName = !(typeof (name) == "undefined");
   if (t == 'text' || t == 'hidden' || t == 'password' || tag == 'textarea') {
    this.value = '';
    kendoWidgetSetValue(that, '');
   } else if (t == 'file') {
    var file = $(this);
    // fix:kendo封装的组件,不能清除.
    if (file.data('kendoBootstrapFileInput')) {
     return;
    }
    if (!file.hasClass('textbox-value')) {
     var newfile = file.clone().val('');
     newfile.insertAfter(file);
     if (file.data('validatebox')) {
      file.validatebox('destroy');
      newfile.validatebox();
     } else {
      file.remove();
     }
    }
   } else if (t == 'checkbox' || t == 'radio') {
    this.checked = false;
   } else if (tag == 'select') {
    this.selectedIndex = -1;
   } else if (tag == 'span' && hasName) {
    $(that).text('');
   } else if (tag == 'img' && hasName) {
    $(that).prop('src', '');
   } else if (tag == 'p' && hasName) {
    $(that).html('');
   }
  });

  var form = $(target);
  var opts = $.data(target, 'form').options;
  for (var i = opts.fieldTypes.length - 1; i >= 0; i--) {
   var type = opts.fieldTypes[i];
   var field = form.find('.' + type + '-f');
   if (field.length && field[type]) {
    field[type]('clear');
   }
  }
  form.form('validate');
 }

 function reset(target) {
  target.reset();
  var form = $(target);
  var opts = $.data(target, 'form').options;
  for (var i = opts.fieldTypes.length - 1; i >= 0; i--) {
   var type = opts.fieldTypes[i];
   var field = form.find('.' + type + '-f');
   if (field.length && field[type]) {
    field[type]('reset');
   }
  }
  form.form('validate');
 }

 /**
  * set the form to make it can submit with ajax.
  */
 function setForm(target) {
  var options = $.data(target, 'form').options;
  $(target).unbind('.form');
  if (options.ajax) {
   $(target).bind('submit.form', function() {
    setTimeout(function() {
     ajaxSubmit(target, options);
    }, 0);
    return false;
   });
  }
  $(target).bind('_change.form', function(e, t) {
   options.onChange.call(this, t);
  }).bind('change.form', function(e) {
   var t = e.target;
   if (!$(t).hasClass('textbox-text')) {
    options.onChange.call(this, t);
   }
  });
  setValidation(target, options.novalidate);
 }

 function initForm(target, options) {
  options = options || {};
  var state = $.data(target, 'form');
  if (state) {
   $.extend(state.options, options);
  } else {
   $.data(target, 'form', {
    options : $.extend({}, $.fn.form.defaults, $.fn.form.parseOptions(target), options)
   });
  }
 }

 function validate(target) {
  if ($.fn.validatebox) {
   var t = $(target);
   t.find('.validatebox-text:not(:disabled)').validatebox('validate');
   var invalidbox = t.find('.validatebox-invalid');
   invalidbox.filter(':not(:disabled):first').focus();
   return invalidbox.length == 0;
  }
  return true;
 }

 function setValidation(target, novalidate) {
  var opts = $.data(target, 'form').options;
  opts.novalidate = novalidate;
  $(target).find('.validatebox-text:not(:disabled)').validatebox(novalidate ? 'disableValidation' : 'enableValidation');
 }

 $.fn.form = function(options, param) {
  if (typeof options == 'string') {
   this.each(function() {
    initForm(this);
   });
   return $.fn.form.methods[options](this, param);
  }

  return this.each(function() {
   initForm(this, options);
   setForm(this);
  });
 };

 $.fn.form.methods = {
  options : function(jq) {
   return $.data(jq[0], 'form').options;
  },
  submit : function(jq, options) {
   return jq.each(function() {
    ajaxSubmit(this, options);
   });
  },
  load : function(jq, data) {
   return jq.each(function() {
    //load之前先clear,避免数据残留
    clear(this);
    load(this, data);
   });
  },
  clear : function(jq) {
   return jq.each(function() {
    clear(this);
   });
  },
  reset : function(jq) {
   return jq.each(function() {
    reset(this);
   });
  },
  validate : function(jq) {
   return validate(jq[0]);
  },
  disableValidation : function(jq) {
   return jq.each(function() {
    setValidation(this, true);
   });
  },
  enableValidation : function(jq) {
   return jq.each(function() {
    setValidation(this, false);
   });
  }
 };

 $.fn.form.parseOptions = function(target) {
  var t = $(target);
  return $.extend({}, $.parser.parseOptions(target, [ {
   ajax : 'boolean'
  } ]), {
   url : (t.attr('action') ? t.attr('action') : undefined)
  });
 };

 $.fn.form.defaults = {
  fieldTypes : [ 'combobox', 'combotree', 'combogrid', 'datetimebox', 'datebox', 'combo', 'datetimespinner', 'timespinner',
   'numberspinner', 'spinner', 'slider', 'searchbox', 'numberbox', 'textbox', 'switchbutton' ],
  novalidate : false,
  ajax : true,
  url : null,
  queryParams : {},
  onSubmit : function(param) {
   return $(this).form('validate');
  },
  success : function(data) {
  },
  onBeforeLoad : function(param) {
  },
  onLoadSuccess : function(data) {
  },
  onLoadError : function() {
  },
  onChange : function(target) {
  }
 };
})(jQuery);
